#!/usr/bin/ruby

#纸牌
PT_NAMES = {PT_1_AGAIN:10,PT_2_AGAIN:10,PT_SWICH:20,PT_ADD_1:20}
CARDS_VAL = {1=>10,2=>10,3=>20}

class PaperTag
	#预先混入(注意不能用include,那个是事后混入)ThreaIO,以便于重载类PaperTag中的
	#puts,printf,gets之类的IO方法(gets是Kernel中定义的私有方法,被混入Object中)
	prepend ThreadIO
	attr_reader :desc,:val,:name

	def initialize(name,val,how_use=nil,desc="")
		@name,@val,@how_use,@desc = name,val,how_use,desc
		if how_use
			#由于proc的闭包性,所以默认how_use代码块中绑定的是全局上下文,即puts绑定的是全局中的puts
			#这显然不满足druby向远程客户端打印的要求!所以要将how_use的转换为method(method不是闭包!),
			#然后在PaperTag类的上下文中调用,这样就达到使用重载IO方法的目的!
			#self.class.class_eval {define_method(:real_use,&how_use)}
			#不能用上行代码,原因是这样将real_use定义在PaperTag类中,所有类的实例共享该方法,所以
			#后面定义的会"覆写"前面定义的代码!只能定义在特定实例的元类中,相当于定义特定实例的单例方法.
=begin
			class << self
				define_method(:real_use,&how_use)
			end
=end			
			meta_class = class << self;self end
			meta_class.class_eval {define_method(:real_use,&how_use)}
		end
	end
	
	def use(c1,c2,stock)
		#puts("hello pt!!!!!")
		#@how_use[c1,c2,stock]
		real_use(c1,c2,stock)
	end
	
	def to_s
		"[#@name(#@val py)]"
	end
end

class PaperTag_l
	attr_reader :desc,:val,:name

	def initialize(name,val,how_use=nil,desc="")
		@name,@val,@how_use,@desc = name,val,how_use,desc
		if how_use
			meta_class = class << self;self end
			meta_class.class_eval {define_method(:real_use,&how_use)}
		end
	end
	
	def use(c1,c2,stock)
		real_use(c1,c2,stock)
	end
	
	def to_s
		"[#@name(#@val py)]"
	end
end

#动态设置pt_swich的use方法
#返回[c1,c2,true]
#如果不满足使用条件则原样返回[c1,c2,false]
proc_use_pt_swich = lambda do |c1,c2,stock|
	m_name = "use_pt_swich"
	is_used = false
	#检查使用条件是否满足
	if stock.count == 0
		puts("#{m_name}:没有卡片了,无法使用PT!!!")
		return [c1,c2,is_used]
	end
	
	#c2已经翻开不能再用PT_SWICH
	if c2 
		puts("c2已经翻开,不可以再用PT_SWICH!")
		return [c1,c2,is_used]
	end
	
	is_used = true
	c2 =  stock.pick_card("#{m_name}:turning 2nd card...")
	c1,c2 = c2,c1
	puts("#{m_name}:after swich c1 is #{Pokers.color_str(c1)} , c2 is #{Pokers.color_str(c2)}")
	[c1,c2,is_used]
end

#动态设置pt_1_again的use方法
proc_use_pt_1_again = lambda do |c1,c2,stock|
	m_name = "use_pt_1_again"
	is_used = false
	#检查使用条件是否满足
	if stock.count == 0
		puts("#{m_name}:没有卡片了,无法使用PT!!!")
		return [c1,c2,is_used]
	end
	
	#如果c2已经翻开,则禁止使用PT_1_AGAIN
	if c2
		puts("c2已经翻开,不可以使用PT_1_AGAIN")
		return [c1,c2,is_used]
	end
	
	is_used = true
	c1 = stock.pick_card("#{m_name}:returning 1st card...")
	[c1,c2,is_used]
end

#动态设置pt_2_again的use方法
proc_use_pt_2_again = lambda do |c1,c2,stock|
	m_name = "use_pt_2_again"
	is_used = false
	#检查使用条件是否满足
	if stock.count == 0
		puts("#{m_name}:没有卡片了,无法使用PT!!!")
		return [c1,c2,is_used]
	end
	
	#如果c2还没翻开禁止使用PT_2_AGAIN
	unless c2
		puts("c2还未翻开,不可以使用PT_2_AGAIN")
		return [c1,c2,is_used]
	end
	
	is_used = true
	c2 = stock.pick_card("#{m_name}:returning 2nd card...")
	[c1,c2,is_used]
end

#动态设置pt_add_1的use方法
proc_use_pt_add_1 = lambda do |c1,c2,stock|
	m_name = "use_pt_add_1"
	is_used = false
	#检查使用条件是否满足
	#FIXME:任何时候都能用?
	
	is_used = true
	#如果c2还没翻开则增加c1,否则增加c2
	unless c2
		c1 = Pokers.add_val(c1,1)
		puts("#{m_name}:c1加1后变为#{Pokers.color_str(c1)}")
	else
		c2 = Pokers.add_val(c2,1)
		puts("#{m_name}:c2加1后变为#{Pokers.color_str(c2)}")
	end
	[c1,c2,is_used]
end

#动态设置pt_sub_1的use方法
proc_use_pt_sub_1 = lambda do |c1,c2,stock|
	m_name = "use_pt_sub_1"
	is_used = false
	#检查使用条件是否满足
	#FIXME:任何时候都能用?
	
	is_used = true
	#如果c2还没翻开则增加c1,否则增加c2
	unless c2
		c1 = Pokers.add_val(c1,-1)
		puts("#{m_name}:c1减1后变为#{Pokers.color_str(c1)}")
	else
		c2 = Pokers.add_val(c2,-1)
		puts("#{m_name}:c2减1后变为#{Pokers.color_str(c2)}")
	end
	[c1,c2,is_used]
end

#动态设置pt_add_5的use方法
proc_use_pt_add_5 = lambda do |c1,c2,stock|
	m_name = "use_pt_add_5"
	is_used = false
	#检查使用条件是否满足
	#FIXME:任何时候都能用?
	
	is_used = true
	#如果c2还没翻开则增加c1,否则增加c2
	unless c2
		c1 = Pokers.add_val(c1,5)
		puts("#{m_name}:c1加5后变为#{Pokers.color_str(c1)}")
	else
		c2 = Pokers.add_val(c2,5)
		puts("#{m_name}:c2加5后变为#{Pokers.color_str(c2)}")
	end
	[c1,c2,is_used]
end

pt_1_again = PaperTag.new("PT_1_AGAIN",10,proc_use_pt_1_again)
pt_2_again = PaperTag.new("PT_2_AGAIN",10,proc_use_pt_2_again)
pt_swich = PaperTag.new("PT_SWICH",20,proc_use_pt_swich)
pt_add_1 = PaperTag.new("PT_ADD_1",20,proc_use_pt_add_1)
pt_add_5 = PaperTag.new("PT_ADD_5",100,proc_use_pt_add_5)
pt_sub_1 = PaperTag.new("PT_SUB_1",20,proc_use_pt_sub_1)

PAPER_TAGS = [pt_1_again,pt_2_again,pt_swich,pt_add_1,pt_add_5,pt_sub_1]
